package com.netsdk.module;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

import com.netsdk.common.SavePath;
import com.netsdk.lib.NetSDKLib;
import com.netsdk.lib.NetSDKLib.LLong;
import com.netsdk.lib.NetSDKLib.NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY;
import com.netsdk.lib.NetSDKLib.NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY;
import com.netsdk.lib.ToolKits;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;

/**
 * 登陆接口实现 主要有 ：初始化、登陆、登出功能
 */
public class LoginModule {

	public static NetSDKLib netsdk = NetSDKLib.NETSDK_INSTANCE;
	public static NetSDKLib configsdk = NetSDKLib.CONFIG_INSTANCE;

	// 设备信息
	public static NetSDKLib.NET_DEVICEINFO_Ex m_stDeviceInfo = new NetSDKLib.NET_DEVICEINFO_Ex();

	// 登陆句柄
	public static LLong m_hLoginHandle = new LLong(0);

	private static boolean bInit = false;
	private static boolean bLogopen = false;
	
	//private static ArrayBlockingQueue<Sring> queue=new ConcurrentBlockBlockingQueue<String>();
	

	public static boolean snapPicture(int type,int chn, int mode, int interval) {
		netsdk.CLIENT_SetSnapRevCallBack(new NetSDKLib.fSnapRev() {		
			@Override
			public void invoke(LLong lLoginID, Pointer pBuf, int RevLen, int EncodeType, int CmdSerial, Pointer dwUser) {
				if (pBuf != null && RevLen > 0) {
					String strFileName = SavePath.getSavePath().getSaveCapturePath();
					//System.err.println(strFileName);
					//System.out.println("strFileName = " + strFileName);
					byte[] buf = pBuf.getByteArray(0, RevLen);
					
//					byte[] buf = pBuf.getByteArray(0, RevLen);
//					String base64String = Base64.encodeBase64String(buf);
					//System.out.println("Dahua:type"+type+":"+11);
					//PostAlarmDataUtils.sendDahuaMsg();
					
					
					String xx=strFileName.substring(strFileName.lastIndexOf("/"));
					System.err.println("event:"+type+"#"+xx);
					try(ByteArrayInputStream byteArrInput = new ByteArrayInputStream(buf)){
						BufferedImage bufferedImage = ImageIO.read(byteArrInput);
						if (bufferedImage == null) {
							return;
						}
						ImageIO.write(bufferedImage, "jpg", new File("D:/333"+xx));//+strFileName));
					} catch (IOException e) {
						e.printStackTrace();
					}
					
					
					
//					ByteArrayInputStream byteArrInput = new ByteArrayInputStream(buf);
//					try {
//						BufferedImage bufferedImage = ImageIO.read(byteArrInput);
//						if (bufferedImage == null) {
//							return;
//						}
//						ImageIO.write(bufferedImage, "jpg", new File("D:/333/"+xx));//+strFileName));
//					} catch (IOException e) {
//						e.printStackTrace();
//					}

				}
			}
		}, null);
		
		
		
		
		
		// send caputre picture command to device
		NetSDKLib.SNAP_PARAMS stuSnapParams = new NetSDKLib.SNAP_PARAMS();
		stuSnapParams.Channel = chn; // channel
		stuSnapParams.mode = mode; // capture picture mode
		stuSnapParams.Quality = 3; // picture quality
		stuSnapParams.InterSnap = interval; // timer capture picture time interval
		stuSnapParams.CmdSerial = 0; // request serial

		IntByReference reserved = new IntByReference(0);
		if (!netsdk.CLIENT_SnapPictureEx(m_hLoginHandle, stuSnapParams, reserved)) {
			System.err.printf("CLIENT_SnapPictureEx Failed!" + ToolKits.getErrorCodePrint());
			return false;
		} else {
			System.out.println("CLIENT_SnapPictureEx success");
		}
		return true;
	}

	/**
	 * \if ENGLISH_LANG Init \else 初始化 \endif
	 */
	public static boolean init(NetSDKLib.fDisConnect disConnect, NetSDKLib.fHaveReConnect haveReConnect) {
		bInit = netsdk.CLIENT_Init(disConnect, null);
		if (!bInit) {
			System.out.println("Initialize SDK failed");
			return false;
		}

		// 打开日志，可选
		NetSDKLib.LOG_SET_PRINT_INFO setLog = new NetSDKLib.LOG_SET_PRINT_INFO();
		File path = new File("./sdklog/");
		if (!path.exists()) {
			path.mkdir();
		}
		String logPath = path.getAbsoluteFile().getParent() + "\\sdklog\\" + ToolKits.getDate() + ".log";
		setLog.nPrintStrategy = 0;
		setLog.bSetFilePath = 1;
		System.arraycopy(logPath.getBytes(), 0, setLog.szLogFilePath, 0, logPath.getBytes().length);
		System.out.println(logPath);
		setLog.bSetPrintStrategy = 1;
		bLogopen = netsdk.CLIENT_LogOpen(setLog);
		if (!bLogopen) {
			System.err.println("Failed to open NetSDK log");
		}

		// 设置断线重连回调接口，设置过断线重连成功回调函数后，当设备出现断线情况，SDK内部会自动进行重连操作
		// 此操作为可选操作，但建议用户进行设置
		netsdk.CLIENT_SetAutoReconnect(haveReConnect, null);

		// 设置登录超时时间和尝试次数，可选
		int waitTime = 5000; // 登录请求响应超时时间设置为5S
		int tryTimes = 1; // 登录时尝试建立链接1次
		netsdk.CLIENT_SetConnectTime(waitTime, tryTimes);

		// 设置更多网络参数，NET_PARAM的nWaittime，nConnectTryNum成员与CLIENT_SetConnectTime
		// 接口设置的登录设备超时时间和尝试次数意义相同,可选
		NetSDKLib.NET_PARAM netParam = new NetSDKLib.NET_PARAM();
		netParam.nConnectTime = 10000; // 登录时尝试建立链接的超时时间
		netParam.nGetConnInfoTime = 3000; // 设置子连接的超时时间
		netParam.nGetDevInfoTime = 3000;// 获取设备信息超时时间，为0默认1000ms
		netsdk.CLIENT_SetNetworkParam(netParam);

		return true;
	}

	/**
	 * \if ENGLISH_LANG CleanUp \else 清除环境 \endif
	 */
	public static void cleanup() {
		if (bLogopen) {
			netsdk.CLIENT_LogClose();
		}

		if (bInit) {
			netsdk.CLIENT_Cleanup();
		}
	}

	/**
	 * \if ENGLISH_LANG Login Device \else 登录设备 \endif
	 */
	public static boolean login(String m_strIp, int m_nPort, String m_strUser, String m_strPassword) {
		// IntByReference nError = new IntByReference(0);
		// 入参
		NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY pstInParam = new NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY();
		pstInParam.nPort = m_nPort;
		pstInParam.szIP = m_strIp.getBytes();
		pstInParam.szPassword = m_strPassword.getBytes();
		pstInParam.szUserName = m_strUser.getBytes();
		// 出参
		NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY pstOutParam = new NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY();
		pstOutParam.stuDeviceInfo = m_stDeviceInfo;
		// m_hLoginHandle = netsdk.CLIENT_LoginEx2(m_strIp, m_nPort, m_strUser,
		// m_strPassword, 0, null, m_stDeviceInfo, nError);
		m_hLoginHandle = netsdk.CLIENT_LoginWithHighLevelSecurity(pstInParam, pstOutParam);
		if (m_hLoginHandle.longValue() == 0) {
			System.err.printf("Login Device[%s] Port[%d]Failed. %s\n", m_strIp, m_nPort, ToolKits.getErrorCodePrint());
		} else {
			System.out.println("Login Success [ " + m_strIp + " ]");
		}

		return m_hLoginHandle.longValue() == 0 ? false : true;
	}
	
	public static boolean isLogout() {
		if (m_hLoginHandle.longValue() == 0) {
			return true;
		}
		return false;
	}
	

	/**
	 * \if ENGLISH_LANG Logout Device \else 登出设备 \endif
	 */
	public static boolean logout() {
		if (m_hLoginHandle.longValue() == 0) {
			return false;
		}

		boolean bRet = netsdk.CLIENT_Logout(m_hLoginHandle);
		if (bRet) {
			m_hLoginHandle.setValue(0);
		}

		return bRet;
	}
}
